package multi_thread.advanced;

import multi_thread.master.lock_aqs.ReentrantReadWriteLockExample;

import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @author Cheng Jun
 * Description: CopyOnWriteArrayList 适合 读多写少、容器中数据量较小、对数据实时一致性要求不高 的场景，
 * 修改时通过 复制一份新的数据 ，然后追加数据
 * CopyOnWriteArraySet 内部就是 一个 CopyOnWriteArrayList 变量，主要是新增的时候 判断唯一性（通过遍历所有数组元素进行判断）。
 * CopyOnWrite容器也是一种读写分离的思想
 * COWIterator 获取的时 COW容器的 快照。后续对COW容器的修改不会影响 COWIterator里面的数据。
 *
 * COW 容器的缺点：
 * 1.内存占用问题，每次写的时候都要复制一份；
 * 2.因为写时复制，所以数据不能做到实时一致性，只能保证数据的最终一致性
 * 3.容器只有 list 和 set 的实现，比较单一，ReentrantReadWriteLock 可以对任意资源进行 读写分离
 * 开发中可以考虑使用 ReentrantReadWriteLock，ReentrantReadWriteLock 还能提供 公平性与非公平性的选择
 * @version 1.0
 * @date 2021/10/14 20:02
 * @see CopyOnWriteArrayList
 * @see ReentrantReadWriteLockExample
 */
public class COWExample {

    public static void main(String[] args) {
        CopyOnWriteArrayList<String> nameList = new CopyOnWriteArrayList<>();
        CopyOnWriteArraySet<String> companySet = new CopyOnWriteArraySet<>();
        // CopyOnWriteArraySet的add方法，检查是否重复，采用的是从头到尾遍历整个数组元素 与待加入的元素比较
        companySet.add("cauchy");
        // 看源码 add方法
        nameList.add("cauchy");
        // Iterator 是获取 snapshot of this list，后续的操作不影响 这个 iterator
        Iterator<String> iterator = nameList.iterator();
        nameList.add("cauchy6317");
        // 这个迭代器不支持 remove
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        System.out.println("------------------------");
        for (String name : nameList) {
            System.out.println(name);
        }
    }
}
